library ieee;
 use ieee.std_logic_1164.all;
 use ieee.std_logic_unsigned.all;

library work;
 use work.router_pack.all;

-------------------------------------------------------------------------------
entity spa is
-------------------------------------------------------------------------------
generic(
  SPA_WIDTH_G : integer := 2  -- Width of the SPA (number of request/grants)
);
port( 
      RESET   : in  std_logic;
 
      -- MUTEX input i/f: --
      R       : in  std_logic_vector(SPA_WIDTH_G-1 downto 0);
      EN      : in  std_logic; -- enable to start arbitration
      GATE    : in  std_logic; -- until is high no arbitration is done.
      
      -- MUTEX output i/f: --
      G       : out std_logic_vector(SPA_WIDTH_G-1 downto 0)           
);           
-------------------------------------------------------------------------------
end spa ;
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
architecture spa_arch of spa is
-------------------------------------------------------------------------------
component mutex
port( 
      -- MUTEX input i/f: --
      R1      : in  std_logic;
      R2      : in  std_logic;

      -- MUTEX output i/f: --
      G1      : out std_logic;
      G2      : out std_logic
);           
end component;

component srlab2
port(
      RN                             :	in    std_logic;
      SN                             :	in    std_logic;
      Q                              :	out   std_logic;
      QN                             :	out   std_logic
);
end component;


component c_element
port( 
      -- Input i/f: --
      A     : in  std_logic;
      B     : in  std_logic;

      -- output i/f: --
      Q     : out std_logic
);           
end component;

signal g1_arr : std_logic_vector(SPA_WIDTH_G-1 downto 0);
signal g2_arr : std_logic_vector(SPA_WIDTH_G-1 downto 0);
signal g_and_arr : std_logic_vector(SPA_WIDTH_G-1 downto 0);

signal r_or_not_and_en, r_from_latch : std_logic; 

signal sig_high, sig_low :std_logic;

signal pri_mod_out : std_logic_vector(SPA_WIDTH_G-1 downto 0);

signal g_or_not : std_logic; 

begin

sig_high <= '1';
sig_low  <= '0';

r_or_not_and_en <= not ( (R(0) or R(1)) and EN );

u_srlab2: srlab2 
port map( 
      RN    => g_or_not,
      SN    => r_or_not_and_en,

      Q     => r_from_latch, -- lock
      QN    => open
);   


sl_data_latch_gen: for i in 0 to (SPA_WIDTH_G-1) generate

 u_mutex_spa: mutex
 port map( 

      R1      => r_from_latch, -- lock
      R2      => R(i),

      G1      => g1_arr(i),
      G2      => g2_arr(i)
 );

 g_and_arr(i) <= g2_arr(i) and r_from_latch;  -- req + lock

 u_c_element1: c_element
 port map( 
      A     => g2_arr(i),
      B     => pri_mod_out(i),

      Q     => G(i)
 ); 

end generate;

prior_module_proc: process( g1_arr, g_and_arr )
 variable g_arr : std_logic_vector(3 downto 0);
begin
 
 --       Lock0       Free0             Lock1       Free1
 g_arr := g1_arr(0) & g_and_arr(0) & g1_arr(1) & g_and_arr(1); 

 case g_arr is
  when "0110" |    -- VC0 free, VC1 busy
       "0101"  =>  -- VC0 free, VC1 free.
    pri_mod_out <= "01";

  when "1001"  =>  -- VC0 busy, VC1 free
    pri_mod_out <= "10";

  when others=>   -- only VC#1 is empty
    pri_mod_out <= (others=>'0');
 end case;

end process;

g_or_not <= not (GATE or RESET);

-------------------------------------------------------------------------------
end spa_arch;
-------------------------------------------------------------------------------                 

   
-------------------------------------------------------------------------------
configuration  spa_cfg  of spa is
-------------------------------------------------------------------------------
   for spa_arch
   end for;
-------------------------------------------------------------------------------
end  spa_cfg;              
-------------------------------------------------------------------------------
                 
